﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.BaseData.Entitys.Dto.QmsBaseIpqccalendar;
using SHZY.BaseData.Entitys;
using SHZY.BaseData.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SHZY.BaseData.Entitys.Entity.QmsBaseIpqccalendar;
using SHZY.BaseData.Entitys.Dto.QmsBaseIpqccalendar.Schedule;
using SHZY.Extend.Entitys.Dto.Schedule;
using SHZY.Extend.Entitys;
using NPOI.SS.Formula.Functions;

namespace SHZY.BaseData;

/// <summary>
/// 业务实现：日程安排.
/// </summary>
[ApiDescriptionSettings(Tag = "BaseData", Name = "QmsBaseIpqccalendar", Order = 200)]
[Route("api/BaseData/[controller]")]
public class QmsBaseIpqccalendarService : IQmsBaseIpqccalendarService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBaseIpqccalendarEntity> _repository;

    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsbaseIpqccalendarDetailEntity> _repositoryDetail;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    /// <summary>
    /// 初始化一个<see cref="QmsBaseIpqccalendarService"/>类型的新实例.
    /// </summary>
    public QmsBaseIpqccalendarService(
        ISqlSugarRepository<QmsBaseIpqccalendarEntity> qmsBaseIpqccalendarRepository,
        ISqlSugarRepository<QmsbaseIpqccalendarDetailEntity> qmsbaseIpqccalendarDetailEntity,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager)
    {
        _repository = qmsBaseIpqccalendarRepository;
        _repositoryDetail = qmsbaseIpqccalendarDetailEntity;
        _db = context.AsTenant();
        _dataInterfaceService = dataInterfaceService;
        _userManager = userManager;
    }

    /// <summary>
    /// 获取日程安排.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        return (await _repository.FirstOrDefaultAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<QmsBaseIpqccalendarInfoOutput>();
    }

    /// <summary>
    /// 获取日程安排列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBaseIpqccalendarListQueryInput input)
    {
        var queryable = _repository.Context.Queryable<QmsBaseIpqccalendarEntity>()
            .Where(it => it.DeleteMark == null)
            .WhereIF(!string.IsNullOrEmpty(input.year), it => it.Year == SqlFunc.ToInt32(input.year))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.Year == SqlFunc.ToInt32(input.keyword))
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id);

        if (!string.IsNullOrEmpty(input.sidx))
            queryable.OrderBy(input.sidx + " " + input.sort);

        var data = await queryable.Select(it => new QmsBaseIpqccalendarListOutput
        {
            id = it.Id,
            year = it.Year,
            name = it.Name,
            enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "无效", "有效"),
        }).ToPagedListAsync(input.currentPage, input.pageSize);
        return PageResult<QmsBaseIpqccalendarListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 新建日程安排.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] QmsBaseIpqccalendarCrInput input)
    {
        if (await _repository.AnyAsync(x => (x.Year == input.year) && x.DeleteMark == null))
            throw Oops.Oh(ErrorCode.COM1004);

        var entity = input.Adapt<QmsBaseIpqccalendarEntity>();

        var isOk = await _repository.Context
           .Insertable(entity)
           .IgnoreColumns(ignoreNullColumn: true)
           .CallEntityMethod(m => m.Creator())
             .CallEntityMethod(m => m.LastModify())
           .ExecuteCommandAsync();

        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);

    }

    /// <summary>
    /// 更新日程安排.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBaseIpqccalendarUpInput input)
    {
        var entity = input.Adapt<QmsBaseIpqccalendarEntity>();
        var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new
        {
            it.Name,
            it.Year,
            it.EnabledMark,
        }).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除日程安排.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        var entity = await _repository.SingleAsync(x => x.Id == id && x.CreatorUserId == _userManager.UserId && x.DeleteMark == null);
        var isOk = await _repository.Context.Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
        if (!isOk)
            throw Oops.Oh(ErrorCode.COM1002);
    }

    /// <summary>
    /// 初始化年度.
    /// </summary>
    /// <param name="year">年度.</param>
    /// <returns></returns>
    [HttpPost("{year}")]
    public async Task Inityear(string year)
    {
        var any = await _repositoryDetail.Context.Queryable<QmsbaseIpqccalendarDetailEntity>().Where(w => w.Year == SqlFunc.ToInt32(year)).AnyAsync();
        if (any)
            throw Oops.Oh(ErrorCode.D1006);

        DateTime start = Convert.ToDateTime(year + "-01-01");
        DateTime end = Convert.ToDateTime(year + "-12 - 31");
        DateTime temp = start;
        while (temp <= end)
        {
            switch (temp.DayOfWeek)
            {
                case DayOfWeek.Saturday:

                case DayOfWeek.Sunday:
                    {
                        await SaveWorkingDayAsync(year, temp, 1);
                        break;
                    }

                default:
                    await SaveWorkingDayAsync(year, temp, 0);
                    break;
            }

            temp = temp.AddDays(1);
        }

    }

    private async Task SaveWorkingDayAsync(string year, DateTime temp, int DateType)
    {
        QmsbaseIpqccalendarDetailEntity detailEntity = new QmsbaseIpqccalendarDetailEntity();
        detailEntity.Year = Convert.ToInt32(year);
        detailEntity.Date = temp;
        detailEntity.DateType = DateType;
        detailEntity.EnabledMark = 1;

        var entity = detailEntity.Adapt<QmsbaseIpqccalendarDetailEntity>();

        await _repositoryDetail.Context
           .Insertable(entity)
           .IgnoreColumns(ignoreNullColumn: true)
           .CallEntityMethod(m => m.Creator())
             .CallEntityMethod(m => m.LastModify())
           .ExecuteCommandAsync();
    }



    #region 日程子表

    /// <summary>
    /// 信息.
    /// </summary>
    /// <param name="id">主键值</param>
    /// <returns></returns>
    [HttpGet("Schedule/ScheduleInfo/{id}")]
    public async Task<dynamic> ScheduleInfo(string id)
    {
        var detail = await _repositoryDetail.FirstOrDefaultAsync(x => x.Id == id && x.DeleteMark == null);
        var info= detail.Adapt<QmsBaseScheduleUpInput>();
        if (info != null)
        {
            info.startTime = detail.Date;
            info.endTime = detail.Date;
        }

        return info;
    }

    /// <summary>
    /// 获取日程安排子表数据.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Schedule/getScheduleList")]
    public async Task<dynamic> getScheduleList([FromQuery] QmsBaseScheduleListQuery input)
    {
        var data = await _repositoryDetail.AsQueryable()
                 .Where(x => x.Date >= input.startTime.ParseToDateTime() && x.Date <= input.endTime.ParseToDateTime() && x.DeleteMark == null)
                 .Select(it => new QmsBaseScheduleListOutput
                 {
                     id = it.Id,
                     content = it.DateRemark == null ? "" : it.DateRemark,
                     startTime = it.Date,
                     endTime = it.Date,
                     colour = SqlFunc.IF(it.DateType == 0).Return("#00FF7F").ElseIF(it.DateType == 1).Return("#FF0000").End("#FF8C00")
                 }).OrderBy(x => x.startTime, OrderByType.Desc).ToListAsync();
        var output = data.Adapt<List<QmsBaseScheduleListOutput>>();
        return new { list = output };
    }

    /// <summary>
    /// 新建.
    /// </summary>
    /// <param name="input">实体对象</param>
    /// <returns></returns>
    [HttpPost("Schedule/ScheduleCreate")]
    public async Task ScheduleCreate([FromBody] QmsBaseScheduleCrInput input)
    {
            List<QmsbaseIpqccalendarDetailEntity> EntityList = new List<QmsbaseIpqccalendarDetailEntity>();
            TimeSpan sp = Convert.ToDateTime(input.endTime).Subtract(Convert.ToDateTime(input.startTime));
            int days = sp.Days;
            var startTime = input.startTime;
            var endTime = input.endTime;

            for (int i = 0; i < days; i++)
            {
                if (startTime <= endTime)
                {
                    QmsbaseIpqccalendarDetailEntity qmsbaseIpqccalendarDetailEntity = new QmsbaseIpqccalendarDetailEntity();
                    qmsbaseIpqccalendarDetailEntity.Year = input.Year;
                    qmsbaseIpqccalendarDetailEntity.Date = startTime;
                    qmsbaseIpqccalendarDetailEntity.DateType = input.DateType;
                    qmsbaseIpqccalendarDetailEntity.DateRemark = input.DateRemark;
                    var entity = qmsbaseIpqccalendarDetailEntity.Adapt<QmsbaseIpqccalendarDetailEntity>();
                    EntityList.Add(entity);
                }
                startTime = Convert.ToDateTime(startTime).AddDays(1);
            }

            var isOk = await _repositoryDetail.Context.Insertable(EntityList).CallEntityMethod(m => m.Creator()).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
            if (isOk < 1)
                throw Oops.Oh(ErrorCode.COM1000);

    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="id">主键值</param>
    /// <param name="input">实体对象</param>
    /// <returns></returns>
    [HttpPut("Schedule/ScheduleUpdate/{id}")]
    public async Task ScheduleUpdate(string id, [FromBody] QmsBaseScheduleUpInput input)
    {
        var isOk = await _repositoryDetail.Context.Updateable<QmsbaseIpqccalendarDetailEntity>().SetColumns(it => new QmsbaseIpqccalendarDetailEntity()
        { DateType = input.DateType, DateRemark = input.DateRemark }).Where(it => it.Date >= input.startTime && it.Date <= input.endTime)
                                                                                            .ExecuteCommandAsync();
        if (isOk < 1)
            throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除.
    /// </summary>
    /// <param name="id">主键值</param>
    /// <returns></returns>
    [HttpDelete("Schedule/ScheduleDelete/{id}")]
    public async Task ScheduleDelete(string id)
    {
        var entity = await _repositoryDetail.FirstOrDefaultAsync(x => x.Id == id && x.DeleteMark == null);
        if (entity == null)
            throw Oops.Oh(ErrorCode.COM1005);
        var isOk = await _repositoryDetail.Context.Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync();
        if (isOk < 1)
            throw Oops.Oh(ErrorCode.COM1002);
    }

    #endregion



}